package com.fly.shiro;

import com.fly.common.model.SysUserModel;
import com.fly.common.util.Global;
import com.fly.common.util.UserlUtil;
import com.fly.system.service.LoginService;
import com.fly.system.service.SysRoleService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/**
 * @CLASSNAME: UserRealm
 * @author: Fly
 * 日期: 2020/6/7  17:44
 * 描述:
 **/
public class UserRealm extends AuthorizingRealm {


    @Autowired
    private LoginService loginService;

    @Autowired
    private SysRoleService sysRoleService;


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
        SysUserModel model = UserlUtil.getUserModel();
        // UsernamePasswordToken upToken = (UsernamePasswordToken) arg0;
        System.out.println("=====进入验证权限方法====");
        Set<String> role = new HashSet<String>();
        Set<String> pms = new HashSet<String>();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        if(model.isAdmin()){
            // 管理员拥有所有权限
            info.addRole("admin");
            info.addStringPermission("*:*:*");
        } else {
            info.setRoles(sysRoleService.findRoleNameByUserId(model.getId()));
            info.setStringPermissions(sysRoleService.findMenuPmsByUserId(model.getId()));
        }
        return info;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
       /* UsernamePasswordToken token = (UsernamePasswordToken)arg0;
        String username = token.getUsername();

        //String password = new String(token.getPassword());
        //char[] cs = Md5Hash.toChars(password.getBytes());
        //System.out.println(username+"====="+password);

        //String password1 = new String((char[]) token.getCredentials());
        ByteSource credentialsSalt = ByteSource.Util.bytes(username);
        SysUserModel sysUserModel = new SysUserModel();
        sysUserModel.setUsername("11");
        sysUserModel.setPassword(new Md5Hash("12111").toHex());
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(sysUserModel,
        															sysUserModel.getPassword(),
        															credentialsSalt,
        															 getName());*/

    	//=========================MD5加密版=========================
        //token携带了用户信息
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) arg0;
        //获取前端输入的用户名
        String userName  = usernamePasswordToken.getUsername();
        //根据用户名查询数据库中对应的记录
        SysUserModel user = loginService.duLogin(userName);
        if(user == null){
            throw new UnknownAccountException("未知账号");
        } else if(!Global.isUserState(user.getState())){
            throw new LockedAccountException("账号被锁定");
        }

        if(user.getId() == 1L && user.getLoginName().equals("admin")){
            user.setAdmin(true);
        }

        //当前realm对象的name
        String realmName = getName();
        //封装用户信息，构建AuthenticationInfo对象并返回
        AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user, user.getPassword(),
        		ByteSource.Util.bytes(user.getSalt()), realmName);
        return authcInfo;
    }


    /**
     * 重写方法,清除当前用户的的 授权缓存
     * @param principals
     */
    public void clearCachedAuthorizationInfo() {
        super.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }

    /**
     * 重写方法，清除当前用户的 认证缓存
     * @param principals
     */
    public void clearCachedAuthenticationInfo() {
        super.clearCachedAuthenticationInfo(SecurityUtils.getSubject().getPrincipals());
    }
    /**
     * 清除某个用户认证和授权缓存
     */
    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    /**
     * 自定义方法：清除所有 授权缓存
     */
    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    /**
     * 自定义方法：清除所有 认证缓存
     */
    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    /**
     * 自定义方法：清除所有的  认证缓存  和 授权缓存
     */
    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }

}
